home *** CD-ROM | disk | FTP | other *** search
/ Practical Algorithms for Image Analysis / Practical Algorithms for Image Analysis.iso / TARFILE.GZ / tarfile / ch_2.4 / xscale / xscale.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-09-11  |  4.1 KB  |  163 lines

  1. /* 
  2.  * xscale.c
  3.  * 
  4.  * Practical Algorithms for Image Analysis
  5.  * 
  6.  * Copyright (c) 1997, 1998, 1999 MLMSoftwareGroup, LLC
  7.  */
  8.  
  9. /*
  10.  * XSCALE 
  11.  *
  12.  * test scale.c module
  13.  * NOTE:  This program is adapted from a fast image
  14.  * scaling algorithm published in the April, 1997, 1998, 1999 MLMSoftwareGroup, LLCe
  15.  * of Doctor Dobb's Journal and is used with permission
  16.  * from the publisher.
  17.  * 
  18.  */
  19.  
  20. #include "xscale.h"
  21.  
  22. extern short tiffInput;         /* flag=0 if no ImageIn to set tags; else =1 */
  23. extern char *optarg;
  24. extern int optind, opterr;
  25.  
  26. /*
  27.  * usage of routine
  28.  */
  29. void
  30. usage (char *progname)
  31. {
  32.   progname = last_bs (progname);
  33.   printf ("USAGE: %s inimg outimg x_scale y_scale [-L]\n", progname);
  34.   printf ("\n%s scales the input image by fast integer interpolation\n", progname);
  35.   printf ("and wrtes the scaled image to the specified output file\n\n");
  36.   printf ("ARGUMENTS:\n");
  37.   printf ("     inimg: input image filename (TIF)\n");
  38.   printf ("    outimg: output image filename (TIF)\n");
  39.   printf ("   x_scale: scaling factor for x-axis (float) >= 0.0\n");
  40.   printf ("   y_scale: scaling factor for y-axis (float) >= 0.0\n\n");
  41.   printf ("OPTIONS:\n");
  42.   printf ("        -L: print Software License for this module\n");
  43.   exit (1);
  44. }
  45.  
  46. void
  47. scale (Image * imgIn, Image * imgOut, double xscale, double yscale)
  48. {
  49.   int x, y;
  50.   int ddax, dday, xzoom, yzoom, i, j, k, yline;
  51.   unsigned char **image_in, **image_out;  /* input/output image */
  52.  
  53.   image_in = imgIn->img;
  54.   image_out = imgOut->img;
  55.  
  56.   /* Calculate the differential amount */
  57.   xzoom = (int) (1.0 / xscale * 1000);
  58.   yzoom = (int) (1.0 / yscale * 1000);
  59.   /* Initialize the output Y value and vertial differential */
  60.   y = 0;
  61.   dday = 0;
  62.   /* Loop over rows in the original image */
  63.   for (i = 0; i < imgIn->height; i++) {
  64.     /* Adjust the vertical accumulated differential, initialize the
  65.      * output X pixel and horizontal accumulated differential */
  66.     dday -= 1000;
  67.     x = 0;
  68.     ddax = 0;
  69.     /* Loop over pixels in the original image */
  70.     for (j = 0; j < imgIn->width; j++) {
  71.       /* Adjust the horizontal accumulated differential */
  72.       ddax -= 1000;
  73.       while (ddax < 0) {
  74.         /* Store values from original image scanline into the scaled
  75.          * buffer until accumulated differential crosses threshold */
  76.         image_out[y][x] = (unsigned char) image_in[i][j];
  77.         x++;
  78.         ddax += xzoom;
  79.       }
  80.     }
  81.     yline = y;
  82.     while (dday < 0) {
  83.       /* The 'outer loop' -- output resized scan lines until the
  84.        * vertical threshold is crossed */
  85.       dday += yzoom;
  86.       for (k = 0; k < x; k++) {
  87.         image_out[y][k] = (unsigned char) image_out[yline][k];
  88.       }
  89.       y++;
  90.       if (y >= imgOut->height)
  91.         y = imgOut->height - 1;
  92.     }
  93.   }
  94. }
  95.  
  96. int
  97. main (int argc, char *argv[])
  98. {
  99.  
  100.   Image *imgIn, *imgOut;
  101.   float xscale, yscale;
  102.   int i_arg;
  103.  
  104. /* 
  105.  * cmd line options:
  106.  */
  107.   static char *optstring = "L";
  108.  
  109.   if (argc < 5)
  110.     usage (argv[0]);
  111.  
  112. /*
  113.  * parse command line
  114.  */
  115.   optind = 5;
  116.   opterr = ON;                  /* give error messages */
  117.  
  118.   while ((i_arg = getopt (argc, argv, optstring)) != EOF) {
  119.     switch (i_arg) {
  120.     case 'L':
  121.       print_sos_lic ();
  122.       exit (0);
  123.     default:
  124.       usage (argv[0]);
  125.       break;
  126.     }
  127.   }
  128.  
  129.   if (!sscanf (argv[3], "%f", &xscale) || xscale <= 0.0) {
  130.     printf ("\nSomething wrong with x scale factor!!!\n");
  131.     usage (argv[0]);
  132.   }
  133.   if (!sscanf (argv[4], "%f", &yscale) || yscale <= 0.0) {
  134.     printf ("\nSomething wrong with y scale factor!!!\n");
  135.     usage (argv[0]);
  136.   }
  137.  
  138. /*
  139.  * read input image
  140.  */
  141.   imgIn = ImageIn (argv[1]);
  142.   if (imgIn->bps == 8 && imgIn->spp == 3) {
  143.     printf ("Got RGB image!!!\nInput image must be Grayscale or B&W!!\n");
  144.     exit (1);
  145.   }
  146.   /* reset tiffInput so that we write a grayscale file (i.e tags are not copied) */
  147.   tiffInput = 0;
  148. /*
  149.  * Allocate memory for output image
  150.  */
  151.   imgOut = ImageAlloc ((int) (yscale * imgIn->height), (int) (xscale * imgIn->width), imgIn->bps);
  152.  
  153. /*
  154.  * Do the scaling
  155.  */
  156.   scale (imgIn, imgOut, (double) xscale, (double) yscale);
  157. /*
  158.  * Write the output image
  159.  */
  160.   ImageOut (argv[2], imgOut);
  161.   return (1);
  162. }
  163.